﻿using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using OpenSoftStore.BusinessLogic.Money;
using OpenSoftStore.BusinessLogic.Product;
using OpenSoftStore.Orm.Logic;
using OpenSoftStore.Orm.Model;
using OpenSoftStore.Orm.Print;
using OpenSoftStore.Orm.View;

namespace OpenSoftStore.BusinessLogic.Member
{
    public class DinnerSaleLogic : ABusinessLogic
    {
        public MoneyLogic MoneyBll;
        private ProductLogic productBll;

        public DinnerSaleLogic()
        {
            MoneyBll = new MoneyLogic();
            productBll = new ProductLogic();
        }

        public int Save(T_DinnerSale dinnerSale, List<T_Borakerage> borakerages = null)
        {
            bool add = true;
            if (string.IsNullOrEmpty(dinnerSale.Id))
            {
                dinnerSale.Id = Guid.NewGuid().ToString("D");
                dinnerSale.AddTime = DateTime.Now;
                dinnerSale.State = "已办理";
            }
            else
            {
                add = false;
                var rDinnerSaleItems = Spa.Where<T_DinnerSaleItem>(" DinnerSaleId = '" + dinnerSale.Id + "'").ToList();
                if (rDinnerSaleItems.Any()) Spa.DeleteObjects(rDinnerSaleItems);
            }

            if (dinnerSale.CashPay > 0) dinnerSale.PayType = "现金";
            if (dinnerSale.BankPay > 0) dinnerSale.PayType += "银行转账/刷卡";
            dinnerSale.RealPay = dinnerSale.CashPay + dinnerSale.BankPay + dinnerSale.ValuePay;

            var dinnerItems = Spa.Where<T_DinnerItem>(" DinnerId =  '" + dinnerSale.DinnerId + "'");
            var tDinnerSaleItems = new List<T_DinnerSaleItem>();
            foreach (var dinnerItem in dinnerItems)
            {
                var dinnerSaleItem = new T_DinnerSaleItem();
                dinnerSaleItem.DinnerSaleId = dinnerSale.Id;
                dinnerSaleItem.Discount = dinnerItem.Discount;
                dinnerSaleItem.LowestPrice = dinnerItem.LowestPrice;
                dinnerSaleItem.MemberId = dinnerSale.MemberId;
                dinnerSaleItem.ObjectId = dinnerItem.ObjectId;
                dinnerSaleItem.TimeLimit = dinnerItem.TimeLimit;
                dinnerSaleItem.TimeLimitArea = dinnerItem.TimeLimit;
                dinnerSaleItem.TimeLimitType = dinnerItem.DinnerId;
                dinnerSaleItem.Times = dinnerItem.Times;
                dinnerSaleItem.Type = dinnerItem.Type;
                tDinnerSaleItems.Add(dinnerSaleItem);

            }

            T_Member member = Spa.Where<T_Member>(m => m.Id == dinnerSale.MemberId).FirstOrDefault();
            member.OwedMoney += dinnerSale.OwedMoney;
            member.HaveValue -= dinnerSale.ValuePay;
            Spa.UpdateObject(member);

            if (add) Spa.AddObject(dinnerSale);
            else Spa.UpdateObject(dinnerSale);
            Spa.AddObjects(tDinnerSaleItems);
            int row = Spa.SaveChanges();

            var lMoney = new L_Money
            {
                TreeId = "a2bc1520-ba09-41fb-94e6-e30e83c84981",
                TreeName = "客户办理套餐",
                Type = "收入",
                CardId = member.CardId,
                ObjectId = dinnerSale.Id,
                BankPayMoney = dinnerSale.BankPay,
                CashPayMoney = dinnerSale.CashPay,
                BankAccountId = dinnerSale.BankAccountId,
                AdminId = dinnerSale.AdminId,
                ShopId = dinnerSale.ShopId
            };
            row += MoneyBll.AddMoeny(lMoney);

            foreach (T_Borakerage borakerage in borakerages)
            {
                borakerage.BillId = dinnerSale.Id;
                borakerage.BroNum = borakerage.RoyaltyRate * dinnerSale.RealPay;
                borakerage.Type = "办套餐";
                borakerage.BrokerageType = "按利润比提成";
                borakerage.RoyaltyRate = borakerage.RoyaltyRate;
                borakerage.AdminId = borakerage.AdminId;
                borakerage.AddTime = DateTime.Now;
                borakerage.SalePrice = dinnerSale.NeedPay;

            }
            productBll.CalculateBorakerage(borakerages);
            return row;
        }

        public int Back(V_DinnerSale vDinnerSal)
        {
            int row = 0;
            var dinnerSale=new T_DinnerSale();
            Spa.CopyPropertiesFrom(dinnerSale, vDinnerSal);
            dinnerSale.CancelTime=DateTime.Now;
            if (dinnerSale.CashCancelPay > 0) dinnerSale.ShopPayType = "现金";
            if (dinnerSale.BankCancelPay > 0) dinnerSale.ShopPayType += "银行转账/刷卡";
            dinnerSale.CancelPay = dinnerSale.CashCancelPay + dinnerSale.BankCancelPay + dinnerSale.ValueCancelPay;
            dinnerSale.State = "已退办";
            row = Spa.Update(dinnerSale);
            var lMoney = new L_Money
            {
                TreeId = "eb330d6a-e3d1-492a-94a5-18c4bff7c701",
                TreeName = "客户退套餐退款",
                Type = "支出",
                CardId = vDinnerSal.MemberCardId,
                ObjectId = vDinnerSal.Id,
                BankPayMoney = vDinnerSal.BankPay,
                CashPayMoney = vDinnerSal.CashPay,
                BankAccountId = vDinnerSal.BankAccountId,
                AdminId = vDinnerSal.AdminId,
                ShopId = vDinnerSal.ShopId
            };
            row += MoneyBll.AddMoeny(lMoney);

            T_Member tMember = Spa.Where<T_Member>(m => m.Id == vDinnerSal.MemberId).FirstOrDefault();
            if (tMember != null)
            {
                tMember.HaveValue += vDinnerSal.ValuePay;
                row+=Spa.Update(tMember);
            }
            productBll.DeleteBorakerage(vDinnerSal.Id);
            return row;
        }

        public List<V_DinnerSale> GetDinnerSalesView(string where = "")
        {
            string sql = " SELECT t1.Id,t1.Times,t2.Id as DinnerId,t2.Name AS DinnerName,  t1.BankPay+t1.CashPay+t1.ValuePay+IIf(IsNull(t3.sReturnMoney),0,t3.sReturnMoney) as RealPay ,  t1.NeedPay,   t1.FavorMoney+iif(isNull(sFavorMoney),0,sFavorMoney) AS FavorMoney,   t1.PayType,   t1.PayMark ,  t1.State,                       t1.AddTime ,   t1.EndTime ,  t1.ShopPayType,   t1.CancelPay ,  t1.CancelMark,  t1.CancelTime  FROM ((SELECT * FROM T_DinnerSale AS a ) AS t1 LEFT JOIN (SELECT * FROM T_Dinner) AS t2 ON t1.DinnerId = t2.Id) LEFT JOIN (SELECT ObjectId, Sum(ReturnMoney) AS sReturnMoney, Sum(FavorMoney) AS sFavorMoney FROM T_MemberReturnMoneyItem AS c GROUP BY ObjectId) AS t3 ON t1.Id = t3.ObjectId  ";
            if (!string.IsNullOrEmpty(where)) sql += where;
            sql += " order by t1.AddTime desc ";
            List<V_DinnerSale> dinnerSales = Spa.SelectWhere<V_DinnerSale>(sql).ToList();
            return dinnerSales;
        }
        public DataTable GetDinnerSalesDataTable(string where = "")
        {
            string sql = " SELECT t1.Id,t1.Times,t2.Id as DinnerId, t2.Name AS DinnerName,  t1.BankPay+t1.CashPay+t1.ValuePay+IIf(IsNull(t3.sReturnMoney),0,t3.sReturnMoney) as RealPay ,  t1.NeedPay,   t1.FavorMoney+iif(isNull(sFavorMoney),0,sFavorMoney) AS FavorMoney,   t1.PayType,   t1.PayMark ,  t1.State,                       t1.AddTime ,   t1.EndTime ,  t1.ShopPayType,   t1.CancelPay ,  t1.CancelMark,  t1.CancelTime  FROM ((SELECT * FROM T_DinnerSale AS a ) AS t1 LEFT JOIN (SELECT * FROM T_Dinner) AS t2 ON t1.DinnerId = t2.Id) LEFT JOIN (SELECT ObjectId, Sum(ReturnMoney) AS sReturnMoney, Sum(FavorMoney) AS sFavorMoney FROM T_MemberReturnMoneyItem AS c GROUP BY ObjectId) AS t3 ON t1.Id = t3.ObjectId  ";
            if (!string.IsNullOrEmpty(where)) sql += where;
            sql += " order by t1.AddTime desc ";
            var dinnerSales = Spa.RunSqLcmdDataSet(sql);
            if (dinnerSales==null) return new DataTable();
            if (dinnerSales.Tables.Count == 0) return new DataTable();
            return dinnerSales.Tables[0];
        }
        public V_DinnerSale GetDinnerSaleObject(string where = "")
        {
            string sql = " select T_DinnerSale.*,T_Dinner.Name as DinnerName,T_Member.Name as MemberName,T_Member.CardId as MemberCardId " +
                       " from (T_DinnerSale inner join T_Dinner on T_Dinner.Id = T_DinnerSale.DinnerId) " +
                       " inner join T_Member on T_Member.Id = T_DinnerSale.MemberId ";
            if (!string.IsNullOrEmpty(where)) sql += where;
            List<V_DinnerSale> dinnerSales = Spa.SelectWhere<V_DinnerSale>(sql).ToList();
            return dinnerSales.FirstOrDefault();
        }

        public DataTable GetDinnerSalesDataTable(string where = "",string orderBy="")
        {
            string sql = " select T_DinnerSale.*,T_Dinner.Name as DinnerName " +
                         " from T_DinnerSale inner join T_Dinner on T_Dinner.Id = T_DinnerSale.DinnerId ";
            if (!string.IsNullOrEmpty(where)) sql += where;
            if (string.IsNullOrEmpty(orderBy)) orderBy = " order by T_DinnerSale.AddTime desc ";
            sql += orderBy;
            var data = Spa.RunSqLcmdDataSet(sql);

            if (data==null) return new DataTable();
            if (data.Tables.Count == 0) return new DataTable();
            return data.Tables[0];
        }

        public DataTable GetDinnerSalesReport(DateTime dtFrom, DateTime dtTo, string where = "", string orderBy = "")
        {
            string sql = string.Format("Select *, (CashPay + BankPay + ValuePay + AllReturn) as AllPay, (FavorMoney + ReturnFavor) as AllFavor, (NeedPay - CashPay - BankPay - ValuePay - FavorMoney - AllReturn - ReturnFavor) as LastOwed  From  (Select a.*,b.Name,b.CardId,b.TelNum,b.CarNo,c.Name as DinnerName from [T_DinnerSale] a,[T_Member] b,[T_Dinner] c  where a.MemberId = b.Id And a.DinnerId = c.Id And a.AddTime >= #{0}# And a.AddTime <= #{1}# ) as t1 left join  (select ObjectId,iif(isnull(Sum(ReturnMoney)),0,Sum(ReturnMoney)) as AllReturn,iif(isnull(Sum(FavorMoney)),0,Sum(FavorMoney)) as ReturnFavor  From [T_MemberReturnMoneyItem] Group by ObjectId) as t2 on t1.Id = t2.ObjectId", dtFrom, dtTo);
            if (!string.IsNullOrEmpty(where)) sql += where;
            if (string.IsNullOrEmpty(orderBy)) orderBy = " order by a.AddTime desc";
            sql += orderBy;
            var dinnerSales = Spa.RunSqLcmdDataSet(sql);
            if (dinnerSales == null) return new DataTable();
            if (dinnerSales.Tables.Count == 0) return new DataTable();
            return dinnerSales.Tables[0];
        }
        
        public DataTable GetDinnerSalesBackReport(DateTime dtFrom,DateTime dtTo,string where = "",string orderBy="")
        {
            string sql = string.Format(" Select a.*,b.Name as DinnerName,c.Name as MemberName,c.CardId,c.TelNum,c.CarNo from   [T_Dinner] b,[T_DinnerSale] a,[T_Member] c Where a.DinnerId = b.Id And c.Id = a.MemberId And a.State = '已退办' And  a.AddTime >= #{0}# And a.AddTime <= #{1}# ", dtFrom, dtTo);
            if (!string.IsNullOrEmpty(where)) sql += where;
            if (string.IsNullOrEmpty(orderBy)) orderBy = " order by a.CancelTime desc";
            sql += orderBy;
            var dinnerSales = Spa.RunSqLcmdDataSet(sql);
            if (dinnerSales == null) return new DataTable();
            if (dinnerSales.Tables.Count == 0) return new DataTable();
            return dinnerSales.Tables[0];
        }

        public DataTable GetDinnerSaleTimesReport(string where = "")
        {
            string sql = " select Max(T_Dinner.Name) as DinnerName,Sum(T_DinnerSale.Times) as Times " +
                         " from (T_DinnerSale inner join T_Dinner on T_Dinner.Id = T_DinnerSale.DinnerId) " +
                         " group by T_DinnerSale.DinnerId ";
            if (!string.IsNullOrEmpty(where)) sql += where;
            var dinnerSales = Spa.RunSqLcmdDataSet(sql);
            if (dinnerSales == null) return new DataTable();
            if (dinnerSales.Tables.Count == 0) return new DataTable();
            return dinnerSales.Tables[0];
        }

        public List<V_DinnerSaleItem> GetDinnerSaleItemsView(string where = "")
        {
            string sql = " select T_DinnerSaleItem.*,T_Product.Name as ProductName ,T_ProductExt.SalePrice as SalePrice,T_Tree.Name as TreeName " +
                         "from ((T_DinnerSaleItem inner join T_Product on T_Product.Id = T_DinnerSaleItem.ObjectId) " +
                         " inner join T_ProductExt on T_Product.Id=T_ProductExt.ProductId) " +
                         " inner join T_Tree on T_Tree.Id=T_Product.TreeId ";
            if (!string.IsNullOrEmpty(where)) sql += where;
            List<V_DinnerSaleItem> dinnerSaleItems = Spa.SelectWhere<V_DinnerSaleItem>(sql).ToList();
            return dinnerSaleItems;
        }

        public List<V_DinnerSale> GetDinnerSaleTimes(string whereStr = "")
        {
            string sql = " select M.Name as MemberName,D.Name as DinnerName,S.Times from (T_DinnerSale as S inner join T_Dinner as D on D.Id=S.DinnerId)";
            sql += " inner join T_Member as M on M.Id=S.MemberId";
            sql += whereStr;
            return Spa.SelectWhere<V_DinnerSale>(sql).ToList();
        }

        public List<P_Dinner> GetDinnerPrint(string where = "", string orderBy = "")
        {
            string sql =
                " select T_Product.Name as ItemName,T_DinnerSale.*,T_Dinner.Name as DinnerName,T_Admin.Name as AdminName,T_DinnerSaleItem.LowestPrice, " +
                " T_Member.Name as MemberName,T_Member.CardId,T_Shop.Name as ShopName,T_Shop.Address as ShopAddress,T_Shop.Tel as ShopTel " +
                " from ((((((T_DinnerSale inner join T_Dinner on T_Dinner.Id = T_DinnerSale.DinnerId) " +
                " inner join T_Shop on T_DinnerSale.ShopId=T_Shop.Id) " +
                " inner join T_Admin on T_DinnerSale.AdminId=T_Admin.Id) " +
                " inner join T_Member on T_DinnerSale.MemberId=T_Member.Id) " +
                " inner join T_DinnerSaleItem on T_DinnerSale.Id =T_DinnerSaleItem.DinnerSaleId) " +
                 " inner join T_Product on T_Product.Id =T_DinnerSaleItem.ObjectId) ";
            if (!string.IsNullOrEmpty(where)) sql = sql + where;
            if (!string.IsNullOrEmpty(orderBy)) sql = sql + orderBy;
            var dinners = Spa.SelectWhere<P_Dinner>(sql).ToList();
            foreach (var dinner in dinners)
            {
                dinner.ItemCount = dinner.Times;
                dinner.ItemTotal = dinner.Times*dinner.LowestPrice;
                dinner.AmountTotal = dinners.Sum(m => m.Times);
            }
            if (!dinners.Any()) return null;
            return dinners;
        }
    }
}
